package com.webwork.mood.system.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.gson.Gson;
import com.webwork.mood.common.controller.SuperCtrl;
import com.webwork.mood.system.dataobject.Branch;
import com.webwork.mood.system.dataobject.Job;
import com.webwork.mood.system.dataobject.User;
import com.webwork.mood.system.service.BranchService;
import com.webwork.mood.system.service.JobService;
import com.webwork.mood.system.service.UserService;
import com.webwork.mood.util.CommonTool;
import com.webwork.mood.util.ExportUtil;
import com.webwork.mood.util.Paging;
import com.webwork.mood.util.RSA;
import com.webwork.mood.util.StrManager;
import com.webwork.mood.util.WriteExcelUtil;

import jxl.CellType;
import jxl.Sheet;
import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.write.WriteException;

@Controller
@RequestMapping(value = "/system")
public class UserController extends SuperCtrl {

	@Autowired
	private UserService userSve;
	
	@Autowired
	private JobService jobSve;
	
	@Autowired
	private BranchService branchSve;
	
	@RequestMapping(value = "/users")
	@Override
	public String mainPage() {
		return "users";
	}
	
	@RequestMapping(value = "queryUsersList")
	@ResponseBody
	public ResponseEntity<String> queryList(
			@RequestParam(value = "page") int page,
			@RequestParam(value = "rows") int rows,
			@RequestParam(required = false, value = "cmd") String cmdStr)
					throws Exception {
		User queryObj = new User();
		if (!StrManager.isEmpty(cmdStr)) {
			queryObj = new Gson().fromJson(cmdStr, User.class);	
		}
		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.add("Content-Type", "text/html; charset=utf-8");
		Map<String, Object> ret = new HashMap<String, Object>();
	
		ret.put("total", userSve.count(queryObj));
		ret.put("rows", userSve.query(queryObj, new Paging(page, rows)));
		
		return new ResponseEntity<String>(new Gson().toJson(ret).toString(), responseHeaders, HttpStatus.CREATED);
	}
	
	@RequestMapping(value = "getUser")
	@ResponseBody
	public ResponseEntity<String> getUser(@RequestParam("userId") String userId) {
		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.add("Content-Type", "text/html; charset=utf-8");
		User user = userSve.get(userId);
		return new ResponseEntity<String>(new Gson().toJson(user).toString(), responseHeaders, HttpStatus.CREATED);
	}
	
	@RequestMapping(value = "addUser")
	@ResponseBody
	public String addUser(@RequestParam("jsonObj") String jsonObj) {
		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.add("Content-Type", "text/html; charset=utf-8");
		User user = new Gson().fromJson(jsonObj, User.class);
		if (userSve.get(user.getUserId()) != null) {
			return EXIST;
		}
		user.setRegistDate(new Date());
		user.setPassword(RSA.encodeBase("555"));	//密码默认为555
		userSve.save(user);
		return SUCCESS;
	}
	
	@RequestMapping(value = "editUser")
	@ResponseBody
	public String editUser(@RequestParam("jsonObj") String jsonObj) {
		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.add("Content-Type", "text/html; charset=utf-8");
		User o = new Gson().fromJson(jsonObj, User.class);
		User user = userSve.get(o.getUserId());
		if (user == null) {
			return NOT_EXIST;
		}
		user.setUserName(o.getUserName());
		user.setJobId(o.getJobId());
		user.setBranchId(o.getBranchId());
		user.setIsManager(o.getIsManager());
		userSve.save(user);
		return SUCCESS;
	}
	
	@RequestMapping(value = "delUser")
	@ResponseBody
	public String delUser(@RequestParam("userId") String userId) {
		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.add("Content-Type", "text/html; charset=utf-8");
		User user = userSve.get(userId);
		if (user == null) {
			return FAIL;
		} else if (user != null && user.getUserId().equalsIgnoreCase("admin")) {
			return "admin";
		}
		userSve.delete(userId);
		return SUCCESS;
	}
	
	@RequestMapping(value = "editPassword")
	@ResponseBody
	public String editPassword(@RequestParam("oldPwd") String oldPwd, @RequestParam("newPwd") String newPwd,
			HttpServletRequest request) {
		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.add("Content-Type", "text/html; charset=utf-8");
		User user = (User) request.getSession(true).getAttribute("user");
		if (!user.getPassword().equals(RSA.encodeBase(oldPwd))) {
			return FAIL;
		}
		user.setPassword(RSA.encodeBase(newPwd));
		userSve.update(user);
		return SUCCESS;
	}
	
	private String[] TEMPLATE_HEAD = { "用户编号", "用户姓名", "联系方式", "所属部门", "所属网点", "是否管理岗"};
	private CellType[] TEMPLATE_TYPE = { CellType.LABEL, CellType.LABEL, CellType.LABEL, CellType.LABEL, CellType.LABEL, CellType.LABEL };
	
	@RequestMapping(value = "importUsers")
	@ResponseBody
	public ResponseEntity<String> importUsers(
			@RequestParam("filePath") String filePath,
			HttpServletRequest request) throws Exception {
		Map<String, String> stateMap = new HashMap<String, String>();
		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.add("Content-Type", "text/html; charset=utf-8");
		filePath = filePath == null ? "" : filePath;
		String ctxPath = request.getSession().getServletContext().getRealPath("/") + filePath;	//获取全路径
		List<String> list = new ArrayList<String>();	//记录sku为空和其他错误原因
		String recordMsg = "";
		int successCount = 0;
		int errorCount = 0;
		int i = 0;
		try {
			if (!ctxPath.endsWith("xls")) {
				stateMap.put("STATE", "error");
				stateMap.put("errorMsg", "传输失败，请上传Excel 97-2003  的xls格式文件。");
				return new ResponseEntity<String>(new Gson().toJson(stateMap), responseHeaders, HttpStatus.CREATED);
			}
			//创建一个可写入的excel文件对象
			File file = new File(ctxPath);
			if (!file.exists()) {
				stateMap.put("STATE", "error");
				stateMap.put("errorMsg", "传输失败，请重试。如果问题再次发生请联系管理员。");
				return new ResponseEntity<String>(new Gson().toJson(stateMap), responseHeaders, HttpStatus.CREATED);
			}
			WorkbookSettings workbooksetting = new WorkbookSettings();
			workbooksetting.setCellValidationDisabled(true);
			Workbook book = Workbook.getWorkbook(file, workbooksetting);
			//使用第一张工作表
			Sheet sheet = book.getSheet(0);
			if (!this.checkFileHeader(sheet)) {
				stateMap.put("STATE", "error");
				stateMap.put("errorMsg", "表头数据错误，请重新下载模板，正确填写数据后再上传。");
				return new ResponseEntity<String>(new Gson().toJson(stateMap), responseHeaders, HttpStatus.CREATED);
			}

			int rows = sheet.getRows();	//总行数
			for (i = 1; i <= rows - 1; i++) {
				String userId = sheet.getCell(0, i).getContents().trim();		//用户编号
				String userName = sheet.getCell(1, i).getContents().trim();		//用户名
				String telephone = sheet.getCell(2, i).getContents().trim();	//联系电话
				String jobName = sheet.getCell(3, i).getContents().trim();			//所属部门(只能填写已登记的部门)
				String branchName = sheet.getCell(4, i).getContents().trim();		//所属网点(只能填写已登记的网点)
				String isManager = sheet.getCell(5, i).getContents().trim();	//是否管理岗(表格上为是或者否,其它不符合)
				
				if (StrManager.isEmpty(userId)) {
					list.add("第" + (i + 1) + "行: 用户编号不能为空" + "<br/>");
					errorCount += 1;
					continue;
				}
				if (StrManager.isEmpty(userName)) {
					list.add("第" + (i + 1) + "行: 用户姓名不能为空" + "<br/>");
					errorCount += 1;
					continue;
				}
				if (!StrManager.isEmpty(telephone)) {
					/* ^匹配开始地方$匹配结束地方,[3|4|5|7|8]选择其中一个{4,8},\d从[0-9]选择 
	                {4,8}匹配次数4~8,java中/表示转义,所以在正则表达式中//匹配/,/匹配"" */
					Pattern p = Pattern.compile("^1[3|4|5|7|8][0-9]\\d{4,8}$");
					Matcher m = p.matcher(telephone);
					if (!m.matches()) {
						list.add("第" + (i + 1) + "行: 联系方式格式不正确" + "<br/>");
						errorCount += 1;
						continue;
					}
				} else {
					list.add("第" + (i + 1) + "行: 联系方式不能为空" + "<br/>");
					errorCount += 1;
					continue;
				}
				Job job = new Job();
				if (!StrManager.isEmpty(jobName)) {
					job.setJobName(jobName);
					List<Job> jobs = jobSve.query(job);
					if (jobs == null || jobs.size() < 1) {
						list.add("第" + (i + 1) + "行: 此部门可能未登记" + "<br/>");
						errorCount += 1;
						continue;
					} else {
						job = jobs.get(0);
					}
				} else {
					list.add("第" + (i + 1) + "行: 所属部门不能为空" + "<br/>");
					errorCount += 1;
					continue;
				}
				Branch branch = new Branch();
				if (!StrManager.isEmpty(branchName)) {
					branch.setBranchName(branchName);
					List<Branch> branchs = branchSve.query(branch);
					if (branchs == null || branchs.size() < 1) {
						list.add("第" + (i + 1) + "行: 此网点可能未登记" + "<br/>");
						errorCount += 1;
						continue;
					} else {
						branch = branchs.get(0);
					}
				} else {
					list.add("第" + (i + 1) + "行: 所属网点不能为空" + "<br/>");
					errorCount += 1;
					continue;
				}
				int im = -1;
				if (!StrManager.isEmpty(isManager)) {
					if (!isManager.equals("是") && !isManager.equals("否")) {
						list.add("第" + (i + 1) + "行: 是否管理岗只能填写是或否" + "<br/>");
						errorCount += 1;
						continue;
					} else {
						if (isManager.equals("是")) {
							im = 1;
						} else if (isManager.equals("否")) {
							im = 0;
						}
					}
				} else {
					list.add("第" + (i + 1) + "行: 是否管理岗不能为空" + "<br/>");
					errorCount += 1;
					continue;
				}
				User user = userSve.get(userId);
				if (user != null) {
					user.setUserName(userName);
					user.setTelephone(telephone);
					user.setJobId(job.getJobId());
					user.setBranchId(branch.getBranchId());
					user.setIsManager(im);
				} else {
					user = new User();
					user.setUserId(userId);
					user.setUserName(userName);
					user.setTelephone(telephone);
					user.setJobId(job.getJobId());
					user.setBranchId(branch.getBranchId());
					user.setIsManager(im);
					user.setRegistDate(new Date());
					user.setPassword(RSA.encodeBase("555"));
				}
				userSve.save(user);
				successCount += 1;
			}
			book.close();
			stateMap.put("STATE", "success");
			stateMap.put("totleCount", rows - 1 + "");
			stateMap.put("successCount", successCount + "");
			stateMap.put("errorCount", errorCount + "");
			for (int k = 0; k < list.size(); k++) {
				recordMsg += list.get(k);
			}
			stateMap.put("recordMsg", recordMsg);
		} catch (Exception e) {
			e.printStackTrace();
			stateMap.put("STATE", "解析文件失败");
			stateMap.put("errorMsg", "第" + (i + 1) + "行数据有误。出错信息：" + e.toString());
		}
		return new ResponseEntity<String>(new Gson().toJson(stateMap), responseHeaders, HttpStatus.CREATED);
	}

	private boolean checkFileHeader(Sheet sh) {
		if (sh.getColumns() < TEMPLATE_HEAD.length) {
			return false;
		}
		String str = null;
		List<String> list = new ArrayList<String>();
		for (int i = 0; i < TEMPLATE_HEAD.length; i++) {
			str = sh.getCell(i, 0).getContents();
			if (TEMPLATE_HEAD[i].equalsIgnoreCase(str)) {
				list.add(str);
			}
		}
		if (list.size() == TEMPLATE_HEAD.length) {
			return true;
		}
		return false;
	}
	
	/**
	 * 导出用户账号模板
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "downlodFile")
	public void downlodFile(HttpServletResponse response) {
		try {
			String fileFolder = Thread.currentThread().getContextClassLoader().getResource("").getPath();
			String fileName = "用户录入模板.xls";
			List<Object[]> list = new ArrayList<Object[]>();
			File file = CommonTool.fileCreate(fileFolder, fileName);
			WriteExcelUtil.writeExcel(new FileOutputStream(file), TEMPLATE_HEAD, TEMPLATE_TYPE, list);
			ExportUtil.exportFile(response, file, true);
		} catch (IOException | WriteException e) {
			e.printStackTrace();
		}
	}
	
}
